NexusPi Git Node
lib/microReticulum/src/Identity.cpp v1.0.7 (59784a34) Text, 24.59 KB
Tff7b72#Tff7b72include T8b949e"Identity.h"
Tff7b72#Tff7b72include T8b949e"Reticulum.h"
Tff7b72#Tff7b72include T8b949e"Transport.h"
Tff7b72#Tff7b72include T8b949e"Packet.h"
Tff7b72#Tff7b72include T8b949e"Log.h"
Tff7b72#Tff7b72include T8b949e"Utilities/OS.h"
Tff7b72#Tff7b72include T8b949e"Cryptography/Ed25519.h"
Tff7b72#Tff7b72include T8b949e"Cryptography/X25519.h"
Tff7b72#Tff7b72include T8b949e"Cryptography/HKDF.h"
Tff7b72#Tff7b72include T8b949e"Cryptography/Token.h"
Tff7b72#Tff7b72include T8b949e"Cryptography/Random.h"
Tff7b72#Tff7b72include T8b949e<algorithm>
Tff7b72#Tff7b72include T8b949e<string.h>
Tff7b72using Tff7b72namespace T7ee787RNSTb4b4b4;
Tff7b72using Tff7b72namespace T7ee787RNSTff7b72:Tff7b72:T7ee787TypeTff7b72:Tff7b72:T7ee787IdentityTb4b4b4;
Tff7b72using Tff7b72namespace T7ee787RNSTff7b72:Tff7b72:T7ee787CryptographyTb4b4b4;
Tff7b72using Tff7b72namespace T7ee787RNSTff7b72:Tff7b72:T7ee787UtilitiesTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3IdentityTff7b72:Tff7b72:Te6edf3IdentityEntryTff7b72> Te6edf3IdentityTff7b72:Tff7b72:Te6edf3_known_destinationsTb4b4b4;
T8b949e/*static*/ Tffa657bool Te6edf3IdentityTff7b72:Tff7b72:Te6edf3_saving_known_destinations Tff7b72= Tffa657falseTb4b4b4;
T8b949e// CBA
T8b949e// CBA ACCUMULATES
T8b949e/*static*/ T8b949e//uint16_t Identity::_known_destinations_maxsize = 100;
T8b949e/*static*/ Tffa657uint16_t Te6edf3IdentityTff7b72:Tff7b72:Te6edf3_known_destinations_maxsize Tff7b72= T79c0ff100Tb4b4b4;
Te6edf3IdentityTff7b72:Tff7b72:Te6edf3IdentityTb4b4b4(Tffa657bool Te6edf3create_keys T8b949e/*= true*/Tb4b4b4) Tff7b72: Te6edf3_objectTb4b4b4(Tff7b72new Te6edf3ObjectTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3create_keysTb4b4b4) Tb4b4b4{
Te6edf3createKeysTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3MEMTb4b4b4(Ta5d6ff"Ta5d6ffIdentity object created, this: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Tb4b4b4(Tffa657uintptr_tTb4b4b4)Tff7b72thisTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff, data: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Tb4b4b4(Tffa657uintptr_tTb4b4b4)Te6edf3_objectTb4b4b4.Te6edf3getTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Te6edf3IdentityTff7b72:Tff7b72:Te6edf3createKeysTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
T8b949e// CRYPTO: create encryption private keys
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_prv Tff7b72= Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3X25519PrivateKeyTff7b72:Tff7b72:Te6edf3generateTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_prv_bytes Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_prvTff7b72-Tff7b72>Te6edf3private_bytesTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::createKeys: prv bytes: " + _object->_prv_bytes.toHex());
T8b949e// CRYPTO: create signature private keys
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_prv Tff7b72= Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3Ed25519PrivateKeyTff7b72:Tff7b72:Te6edf3generateTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_prv_bytes Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_prvTff7b72-Tff7b72>Te6edf3private_bytesTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::createKeys: sig prv bytes: " + _object->_sig_prv_bytes.toHex());
T8b949e// CRYPTO: create encryption public keys
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pub Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_prvTff7b72-Tff7b72>Te6edf3public_keyTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pub_bytes Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pubTff7b72-Tff7b72>Te6edf3public_bytesTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::createKeys: pub bytes: " + _object->_pub_bytes.toHex());
T8b949e// CRYPTO: create signature public keys
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_pub Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_prvTff7b72-Tff7b72>Te6edf3public_keyTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_pub_bytes Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_pubTff7b72-Tff7b72>Te6edf3public_bytesTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::createKeys: sig pub bytes: " + _object->_sig_pub_bytes.toHex());
Te6edf3update_hashesTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSETb4b4b4(Ta5d6ff"Ta5d6ffIdentity keys created for Ta5d6ff" Tff7b72+ Te6edf3_objectTff7b72-Tff7b72>Te6edf3_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/*
Load a private key into the instance.
:param prv_bytes: The private key as *bytes*.
:returns: True if the key was loaded, otherwise False.
*/
Tffa657bool Te6edf3IdentityTff7b72:Tff7b72:Te6edf3load_private_keyTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3prv_bytesTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
T8b949e//p self.prv_bytes = prv_bytes[:Identity.KEYSIZE//8//2]
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_prv_bytes Tff7b72= Te6edf3prv_bytesTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3KEYSIZETff7b72/T79c0ff8Tff7b72/T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_prv Tff7b72= Te6edf3X25519PrivateKeyTff7b72:Tff7b72:Te6edf3from_private_bytesTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_prv_bytesTb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::load_private_key: prv bytes: " + _object->_prv_bytes.toHex());
T8b949e//p self.sig_prv_bytes = prv_bytes[Identity.KEYSIZE//8//2:]
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_prv_bytes Tff7b72= Te6edf3prv_bytesTb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3KEYSIZETff7b72/T79c0ff8Tff7b72/T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_prv Tff7b72= Te6edf3Ed25519PrivateKeyTff7b72:Tff7b72:Te6edf3from_private_bytesTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_prv_bytesTb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::load_private_key: sig prv bytes: " + _object->_sig_prv_bytes.toHex());
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pub Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_prvTff7b72-Tff7b72>Te6edf3public_keyTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pub_bytes Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pubTff7b72-Tff7b72>Te6edf3public_bytesTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::load_private_key: pub bytes: " + _object->_pub_bytes.toHex());
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_pub Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_prvTff7b72-Tff7b72>Te6edf3public_keyTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_pub_bytes Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_pubTff7b72-Tff7b72>Te6edf3public_bytesTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::load_private_key: sig pub bytes: " + _object->_sig_pub_bytes.toHex());
Te6edf3update_hashesTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
T8b949e//p raise e
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffFailed to load identity keyTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*
Load a public key into the instance.
:param pub_bytes: The public key as *bytes*.
:returns: True if the key was loaded, otherwise False.
*/
Tffa657void Te6edf3IdentityTff7b72:Tff7b72:Te6edf3load_public_keyTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3pub_bytesTb4b4b4) Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
T8b949e//_pub_bytes = pub_bytes[:Identity.KEYSIZE//8//2]
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pub_bytes Tff7b72= Te6edf3pub_bytesTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3KEYSIZETff7b72/T79c0ff8Tff7b72/T79c0ff2Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::load_public_key: pub bytes: " + _object->_pub_bytes.toHex());
T8b949e//_sig_pub_bytes = pub_bytes[Identity.KEYSIZE//8//2:]
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_pub_bytes Tff7b72= Te6edf3pub_bytesTb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3KEYSIZETff7b72/T79c0ff8Tff7b72/T79c0ff2Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::load_public_key: sig pub bytes: " + _object->_sig_pub_bytes.toHex());
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pub Tff7b72= Te6edf3X25519PublicKeyTff7b72:Tff7b72:Te6edf3from_public_bytesTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pub_bytesTb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_pub Tff7b72= Te6edf3Ed25519PublicKeyTff7b72:Tff7b72:Te6edf3from_public_bytesTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_pub_bytesTb4b4b4)Tb4b4b4;
Te6edf3update_hashesTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError while loading public key, the contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657bool Te6edf3IdentityTff7b72:Tff7b72:Te6edf3loadTb4b4b4(Tff7b72const Tffa657charTff7b72* Te6edf3pathTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffReading identity key from storage...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(RNS_USE_FS)
Tff7b72try Tb4b4b4{
Te6edf3Bytes Te6edf3prv_bytesTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3read_fileTb4b4b4(Te6edf3pathTb4b4b4, Te6edf3prv_bytesTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3load_private_keyTb4b4b4(Te6edf3prv_bytesTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffError while loading identity from Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e/*
Saves the identity to a file. This will write the private key to disk,
and anyone with access to this file will be able to decrypt all
communication for the identity. Be very careful with this method.
:param path: The full path specifying where to save the identity.
:returns: True if the file was saved, otherwise False.
*/
Tffa657bool Te6edf3IdentityTff7b72:Tff7b72:Te6edf3to_fileTb4b4b4(Tff7b72const Tffa657charTff7b72* Te6edf3pathTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffWriting identity key to storage...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(RNS_USE_FS)
Tff7b72try Tb4b4b4{
Tff7b72return Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3write_fileTb4b4b4(Te6edf3pathTb4b4b4, Te6edf3get_private_keyTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= Te6edf3get_private_keyTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError while saving identity to %sTa5d6ff"Tb4b4b4, Te6edf3pathTb4b4b4)Tb4b4b4;
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e/*
Create a new :ref:`RNS.Identity<api-identity>` instance from a file.
Can be used to load previously created and saved identities into Reticulum.
:param path: The full path to the saved :ref:`RNS.Identity<api-identity>` data
:returns: A :ref:`RNS.Identity<api-identity>` instance, or *None* if the loaded data was invalid.
*/
T8b949e/*static*/ Tff7b72const Te6edf3Identity Te6edf3IdentityTff7b72:Tff7b72:Te6edf3from_fileTb4b4b4(Tff7b72const Tffa657charTff7b72* Te6edf3pathTb4b4b4) Tb4b4b4{
Te6edf3Identity Td2a8ffidentityTb4b4b4(Tffa657falseTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3identityTb4b4b4.Te6edf3loadTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3identityTb4b4b4;
Tb4b4b4}
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3IdentityTff7b72:Tff7b72:Te6edf3rememberTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3packet_hashTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3public_keyTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3app_data T8b949e/*= {Bytes::NONE}*/Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3public_keyTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3KEYSIZETff7b72/T79c0ff8Tb4b4b4) Tb4b4b4{
Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3invalid_argumentTb4b4b4(Ta5d6ff"Ta5d6ffCan't remember Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff, the public key size of Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3public_keyTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff is not valid.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e//p _known_destinations[destination_hash] = {OS::time(), packet_hash, public_key, app_data};
T8b949e// CBA ACCUMULATES
Te6edf3_known_destinationsTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3destination_hashTb4b4b4, Tb4b4b4{Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packet_hashTb4b4b4, Te6edf3public_keyTb4b4b4, Te6edf3app_dataTb4b4b4}Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*
Recall identity for a destination hash.
:param destination_hash: Destination hash as *bytes*.
:returns: An :ref:`RNS.Identity<api-identity>` instance that can be used to create an outgoing :ref:`RNS.Destination<api-destination>`, or *None* if the destination is unknown.
*/
T8b949e/*static*/ Te6edf3Identity Te6edf3IdentityTff7b72:Tff7b72:Te6edf3recallTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::recall...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_known_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_known_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::recall: Found identity entry for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3IdentityEntryTff7b72& Te6edf3identity_data Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Te6edf3Identity Td2a8ffidentityTb4b4b4(Tffa657falseTb4b4b4)Tb4b4b4;
Te6edf3identityTb4b4b4.Te6edf3load_public_keyTb4b4b4(Te6edf3identity_dataTb4b4b4.Te6edf3_public_keyTb4b4b4)Tb4b4b4;
Te6edf3identityTb4b4b4.Te6edf3app_dataTb4b4b4(Te6edf3identity_dataTb4b4b4.Te6edf3_app_dataTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3identityTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::recall: Unable to find identity entry for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff, performing destination lookup...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3Destination Td2a8ffregistered_destinationTb4b4b4(Te6edf3TransportTff7b72:Tff7b72:Te6edf3find_destination_from_hashTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3registered_destinationTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::recall: Found destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Identity Td2a8ffidentityTb4b4b4(Tffa657falseTb4b4b4)Tb4b4b4;
Te6edf3identityTb4b4b4.Te6edf3load_public_keyTb4b4b4(Te6edf3registered_destinationTb4b4b4.Te6edf3identityTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3get_public_keyTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3identityTb4b4b4.Te6edf3app_dataTb4b4b4(Tb4b4b4{Te6edf3BytesTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3identityTb4b4b4;
Tb4b4b4}
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::recall: Unable to find destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*
Recall last heard app_data for a destination hash.
:param destination_hash: Destination hash as *bytes*.
:returns: *Bytes* containing app_data, or *None* if the destination is unknown.
*/
T8b949e/*static*/ Te6edf3Bytes Te6edf3IdentityTff7b72:Tff7b72:Te6edf3recall_app_dataTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::recall_app_data...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_known_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_known_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::recall_app_data: Found identity entry for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3IdentityEntryTff7b72& Te6edf3identity_data Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72return Te6edf3identity_dataTb4b4b4.Te6edf3_app_dataTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::recall_app_data: Unable to find identity entry for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4{Te6edf3BytesTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3IdentityTff7b72:Tff7b72:Te6edf3save_known_destinationsTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// TODO: Improve the storage method so we don't have to
T8b949e// deserialize and serialize the entire table on every
T8b949e// save, but the only changes. It might be possible to
T8b949e// simply overwrite on exit now that every local client
T8b949e// disconnect triggers a data persist.
Tffa657bool Te6edf3success Tff7b72= Tffa657falseTb4b4b4;
Tff7b72try Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_saving_known_destinationsTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3wait_interval Tff7b72= T79c0ff0.2Tb4b4b4;
Tffa657double Te6edf3wait_timeout Tff7b72= T79c0ff5Tb4b4b4;
Tffa657double Te6edf3wait_start Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3_saving_known_destinationsTb4b4b4) Tb4b4b4{
Te6edf3OSTff7b72:Tff7b72:Te6edf3sleepTb4b4b4(Te6edf3wait_intervalTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3wait_start Tff7b72+ Te6edf3wait_timeoutTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffCould not save known destinations to storage, waiting for previous save operation timed out.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3_saving_known_destinations Tff7b72= Tffa657trueTb4b4b4;
Tffa657double Te6edf3save_start Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3IdentityEntryTff7b72> Te6edf3storage_known_destinationsTb4b4b4;
T8b949e// TODO
T8b949e/*
if os.path.isfile(RNS.Reticulum.storagepath+"/known_destinations"):
try:
file = open(RNS.Reticulum.storagepath+"/known_destinations","rb")
storage_known_destinations = umsgpack.load(file)
file.close()
except:
pass
*/
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3identity_entryTb4b4b4] Tff7b72: Te6edf3storage_known_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_known_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4) Tff7b72=Tff7b72= Te6edf3_known_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e//_known_destinations[destination_hash] = storage_known_destinations[destination_hash];
T8b949e//_known_destinations[destination_hash] = identity_entry;
T8b949e// CBA ACCUMULATES
Te6edf3_known_destinationsTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3destination_hashTb4b4b4, Te6edf3identity_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// TODO
T8b949e/*
DEBUG("Saving " + std::to_string(_known_destinations.size()) + " known destinations to storage...");
file = open(RNS.Reticulum.storagepath+"/known_destinations","wb")
umsgpack.dump(Identity.known_destinations, file)
file.close()
*/
Te6edf3stdTff7b72:Tff7b72:Te6edf3string Te6edf3time_strTb4b4b4;
Tffa657double Te6edf3save_time Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3save_startTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3save_time Tff7b72< T79c0ff1Tb4b4b4) Tb4b4b4{
Te6edf3time_str Tff7b72= Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Tb4b4b4(Tffa657intTb4b4b4)Tb4b4b4(Te6edf3save_timeTff7b72*T79c0ff1000Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff msTa5d6ff"Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3time_str Tff7b72= Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3roundTb4b4b4(Te6edf3save_timeTb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff sTa5d6ff"Tb4b4b4;
Tb4b4b4}
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffSaved known destinations to storage in Ta5d6ff" Tff7b72+ Te6edf3time_strTb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffError while saving known destinations to disk, the contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3_saving_known_destinations Tff7b72= Tffa657falseTb4b4b4;
Tff7b72return Te6edf3successTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3IdentityTff7b72:Tff7b72:Te6edf3load_known_destinationsTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// TODO
T8b949e/*
if os.path.isfile(RNS.Reticulum.storagepath+"/known_destinations"):
try:
file = open(RNS.Reticulum.storagepath+"/known_destinations","rb")
loaded_known_destinations = umsgpack.load(file)
file.close()
Identity.known_destinations = {}
for known_destination in loaded_known_destinations:
if len(known_destination) == RNS.Reticulum.TRUNCATED_HASHLENGTH//8:
Identity.known_destinations[known_destination] = loaded_known_destinations[known_destination]
RNS.log("Loaded "+str(len(Identity.known_destinations))+" known destination from storage", RNS.LOG_VERBOSE)
except:
RNS.log("Error loading known destinations from disk, file will be recreated on exit", RNS.LOG_ERROR)
else:
RNS.log("Destinations file does not exist, no known destinations loaded", RNS.LOG_VERBOSE)
*/
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3IdentityTff7b72:Tff7b72:Te6edf3cull_known_destinationsTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::cull_path_table()Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_known_destinationsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_known_destinations_maxsizeTb4b4b4) Tb4b4b4{
T8b949e// prune by age
Tffa657uint16_t Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Te6edf3IdentityEntryTff7b72>Tff7b72> Te6edf3sorted_pairsTb4b4b4;
T8b949e// Copy key/value pairs from map into vector
Te6edf3stdTff7b72:Tff7b72:Te6edf3for_eachTb4b4b4(Te6edf3_known_destinationsTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_known_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4[Tff7b72&Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Tff7b72const Te6edf3BytesTb4b4b4, Te6edf3IdentityEntryTff7b72>Tff7b72& Te6edf3refTb4b4b4) Tb4b4b4{
Te6edf3sorted_pairsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3refTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
T8b949e// Sort vector using specified comparator
Te6edf3stdTff7b72:Tff7b72:Te6edf3sortTb4b4b4(Te6edf3sorted_pairsTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3sorted_pairsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Te6edf3IdentityEntryTff7b72> Tff7b72&Te6edf3leftTb4b4b4, Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Te6edf3IdentityEntryTff7b72> Tff7b72&Te6edf3rightTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3leftTb4b4b4.Te6edf3secondTb4b4b4.Te6edf3_timestamp Tff7b72< Te6edf3rightTb4b4b4.Te6edf3secondTb4b4b4.Te6edf3_timestampTb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
T8b949e// Iterate vector of sorted values
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3identity_entryTb4b4b4] Tff7b72: Te6edf3sorted_pairsTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::cull_path_table: Removing destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff from known destinationsTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// Remove destination from known destinations
Tff7b72if Tb4b4b4(Te6edf3_known_destinationsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4) Tff7b72< T79c0ff1Tb4b4b4) Tb4b4b4{
Te6edf3WARNINGTb4b4b4(Ta5d6ff"Ta5d6ffFailed to remove destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff from known destinationsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72+Tff7b72+Te6edf3countTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_known_destinationsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72<Tff7b72= Te6edf3_known_destinations_maxsizeTb4b4b4) Tb4b4b4{
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffRemoved Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3countTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff path(s) from known destinationsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3IdentityTff7b72:Tff7b72:Te6edf3validate_announceTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3destination_hash Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::validate_announce: destination_hash: " + packet.destination_hash().toHex());
Te6edf3Bytes Te6edf3public_key Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(Te6edf3KEYSIZETff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::validate_announce: public_key: " + public_key.toHex());
Te6edf3Bytes Te6edf3name_hash Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Te6edf3KEYSIZETff7b72/T79c0ff8Tb4b4b4, Te6edf3NAME_HASH_LENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::validate_announce: name_hash: " + name_hash.toHex());
Te6edf3Bytes Te6edf3random_hash Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Te6edf3KEYSIZETff7b72/T79c0ff8 Tff7b72+ Te6edf3NAME_HASH_LENGTHTff7b72/T79c0ff8Tb4b4b4, Te6edf3RANDOM_HASH_LENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::validate_announce: random_hash: " + random_hash.toHex());
Te6edf3Bytes Te6edf3signature Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Te6edf3KEYSIZETff7b72/T79c0ff8 Tff7b72+ Te6edf3NAME_HASH_LENGTHTff7b72/T79c0ff8 Tff7b72+ Te6edf3RANDOM_HASH_LENGTHTff7b72/T79c0ff8Tb4b4b4, Te6edf3SIGLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::validate_announce: signature: " + signature.toHex());
Te6edf3Bytes Te6edf3app_dataTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3KEYSIZETff7b72/T79c0ff8 Tff7b72+ Te6edf3NAME_HASH_LENGTHTff7b72/T79c0ff8 Tff7b72+ Te6edf3RANDOM_HASH_LENGTHTff7b72/T79c0ff8 Tff7b72+ Te6edf3SIGLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3app_data Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Te6edf3KEYSIZETff7b72/T79c0ff8 Tff7b72+ Te6edf3NAME_HASH_LENGTHTff7b72/T79c0ff8 Tff7b72+ Te6edf3RANDOM_HASH_LENGTHTff7b72/T79c0ff8 Tff7b72+ Te6edf3SIGLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e//TRACE("Identity::validate_announce: app_data: " + app_data.toHex());
T8b949e//TRACE("Identity::validate_announce: app_data text: " + app_data.toString());
Te6edf3Bytes Te6edf3signed_dataTb4b4b4;
Te6edf3signed_data Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4) Tff7b72<Tff7b72< Te6edf3public_key Tff7b72<Tff7b72< Te6edf3name_hash Tff7b72<Tff7b72< Te6edf3random_hashTff7b72+Te6edf3app_dataTb4b4b4;
T8b949e//TRACE("Identity::validate_announce: signed_data: " + signed_data.toHex());
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72<Tff7b72= Te6edf3KEYSIZETff7b72/T79c0ff8 Tff7b72+ Te6edf3NAME_HASH_LENGTHTff7b72/T79c0ff8 Tff7b72+ Te6edf3RANDOM_HASH_LENGTHTff7b72/T79c0ff8 Tff7b72+ Te6edf3SIGLENGTHTff7b72/T79c0ff8Tb4b4b4) Tb4b4b4{
Te6edf3app_dataTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3Identity Te6edf3announced_identityTb4b4b4(Tffa657falseTb4b4b4)Tb4b4b4;
Te6edf3announced_identityTb4b4b4.Te6edf3load_public_keyTb4b4b4(Te6edf3public_keyTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3announced_identityTb4b4b4.Te6edf3pubTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3announced_identityTb4b4b4.Te6edf3validateTb4b4b4(Te6edf3signatureTb4b4b4, Te6edf3signed_dataTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3hash_material Tff7b72= Te6edf3name_hash Tff7b72<Tff7b72< Te6edf3announced_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3expected_hash Tff7b72= Te6edf3full_hashTb4b4b4(Te6edf3hash_materialTb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::validate_announce: destination_hash: " + packet.destination_hash().toHex());
T8b949e//TRACE("Identity::validate_announce: expected_hash: " + expected_hash.toHex());
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3expected_hashTb4b4b4) Tb4b4b4{
T8b949e// Check if we already have a public key for this destination
T8b949e// and make sure the public key is not different.
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_known_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_known_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3IdentityEntryTff7b72& Te6edf3identity_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3public_key Tff7b72!Tff7b72= Te6edf3identity_entryTb4b4b4.Te6edf3_public_keyTb4b4b4) Tb4b4b4{
T8b949e// In reality, this should never occur, but in the odd case
T8b949e// that someone manages a hash collision, we reject the announce.
Te6edf3CRITICALTb4b4b4(Ta5d6ff"Ta5d6ffReceived announce with valid signature and destination hash, but announced public key does not match already known public key.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3CRITICALTb4b4b4(Ta5d6ff"Ta5d6ffThis may indicate an attempt to modify network paths, or a random hash collision. The announce was rejected.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3rememberTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3public_keyTb4b4b4, Te6edf3app_dataTb4b4b4)Tb4b4b4;
T8b949e//p del announced_identity
Te6edf3stdTff7b72:Tff7b72:Te6edf3string Te6edf3signal_strTb4b4b4;
T8b949e// TODO
T8b949e/*
if packet.rssi != None or packet.snr != None:
signal_str = " ["
if packet.rssi != None:
signal_str += "RSSI "+str(packet.rssi)+"dBm"
if packet.snr != None:
signal_str += ", "
if packet.snr != None:
signal_str += "SNR "+str(packet.snr)+"dB"
signal_str += "]"
else:
signal_str = ""
*/
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffValid announce for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops away, received via Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff on Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3signal_strTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffValid announce for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops away, received on Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3signal_strTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffReceived invalid announce for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff: Destination mismatch.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffReceived invalid announce for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff: Invalid signature.Ta5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e//p del announced_identity
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffError occurred while validating announce. The contained exception was: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3IdentityTff7b72:Tff7b72:Te6edf3persist_dataTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3TransportTff7b72:Tff7b72:Te6edf3reticulumTb4b4b4(Tb4b4b4) Tff7b72|Tff7b72| Tff7b72!Te6edf3TransportTff7b72:Tff7b72:Te6edf3reticulumTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3is_connected_to_shared_instanceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3save_known_destinationsTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3IdentityTff7b72:Tff7b72:Te6edf3exit_handlerTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3persist_dataTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/*
Encrypts information for the identity.
:param plaintext: The plaintext to be encrypted as *bytes*.
:returns: Ciphertext token as *bytes*.
:raises: *KeyError* if the instance does not hold a public key.
*/
Tff7b72const Te6edf3Bytes Te6edf3IdentityTff7b72:Tff7b72:Te6edf3encryptTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3plaintextTb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::encrypt: encrypting data...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pubTb4b4b4) Tb4b4b4{
Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3runtime_errorTb4b4b4(Ta5d6ff"Ta5d6ffEncryption failed because identity does not hold a public keyTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3X25519PrivateKeyTff7b72:Tff7b72:Te6edf3Ptr Te6edf3ephemeral_key Tff7b72= Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3X25519PrivateKeyTff7b72:Tff7b72:Te6edf3generateTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3ephemeral_pub_bytes Tff7b72= Te6edf3ephemeral_keyTff7b72-Tff7b72>Te6edf3public_keyTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3public_bytesTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::encrypt: ephemeral public key: Ta5d6ff" Tff7b72+ Te6edf3ephemeral_pub_bytesTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// CRYPTO: create shared key for key exchange using own public key
T8b949e//shared_key = ephemeral_key.exchange(self.pub)
Te6edf3Bytes Te6edf3shared_key Tff7b72= Te6edf3ephemeral_keyTff7b72-Tff7b72>Te6edf3exchangeTb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pub_bytesTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::encrypt: shared key: Ta5d6ff" Tff7b72+ Te6edf3shared_keyTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3derived_key Tff7b72= Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3hkdfTb4b4b4(
Te6edf3DERIVED_KEY_LENGTHTb4b4b4,
Te6edf3shared_keyTb4b4b4,
Te6edf3get_saltTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3get_contextTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::encrypt: derived key: Ta5d6ff" Tff7b72+ Te6edf3derived_keyTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3Token Td2a8fftokenTb4b4b4(Te6edf3derived_keyTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::encrypt: Token encrypting data of length Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3plaintextTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::encrypt: plaintext: Ta5d6ff" Tff7b72+ Te6edf3plaintextTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3ciphertext Tff7b72= Te6edf3tokenTb4b4b4.Te6edf3encryptTb4b4b4(Te6edf3plaintextTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::encrypt: ciphertext: Ta5d6ff" Tff7b72+ Te6edf3ciphertextTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3ephemeral_pub_bytes Tff7b72+ Te6edf3ciphertextTb4b4b4;
Tb4b4b4}
T8b949e/*
Decrypts information for the identity.
:param ciphertext: The ciphertext to be decrypted as *bytes*.
:returns: Plaintext as *bytes*, or *None* if decryption fails.
:raises: *KeyError* if the instance does not hold a private key.
*/
Tff7b72const Te6edf3Bytes Te6edf3IdentityTff7b72:Tff7b72:Te6edf3decryptTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3ciphertext_tokenTb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::decrypt: decrypting data...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_objectTff7b72-Tff7b72>Te6edf3_prvTb4b4b4) Tb4b4b4{
Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3runtime_errorTb4b4b4(Ta5d6ff"Ta5d6ffDecryption failed because identity does not hold a private keyTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3ciphertext_tokenTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72<Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3KEYSIZETff7b72/T79c0ff8Tff7b72/T79c0ff2Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDecryption failed because the token size Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3ciphertext_tokenTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff was invalid.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4{Te6edf3BytesTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
Te6edf3Bytes Te6edf3plaintextTb4b4b4;
Tff7b72try Tb4b4b4{
T8b949e//peer_pub_bytes = ciphertext_token[:Identity.KEYSIZE//8//2]
Te6edf3Bytes Te6edf3peer_pub_bytes Tff7b72= Te6edf3ciphertext_tokenTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3KEYSIZETff7b72/T79c0ff8Tff7b72/T79c0ff2Tb4b4b4)Tb4b4b4;
T8b949e//peer_pub = X25519PublicKey.from_public_bytes(peer_pub_bytes)
T8b949e//Cryptography::X25519PublicKey::Ptr peer_pub = Cryptography::X25519PublicKey::from_public_bytes(peer_pub_bytes);
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::decrypt: peer public key: Ta5d6ff" Tff7b72+ Te6edf3peer_pub_bytesTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// CRYPTO: create shared key for key exchange using peer public key
T8b949e//shared_key = _object->_prv->exchange(peer_pub);
Te6edf3Bytes Te6edf3shared_key Tff7b72= Te6edf3_objectTff7b72-Tff7b72>Te6edf3_prvTff7b72-Tff7b72>Te6edf3exchangeTb4b4b4(Te6edf3peer_pub_bytesTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::decrypt: shared key: Ta5d6ff" Tff7b72+ Te6edf3shared_keyTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3derived_key Tff7b72= Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3hkdfTb4b4b4(
Te6edf3DERIVED_KEY_LENGTHTb4b4b4,
Te6edf3shared_keyTb4b4b4,
Te6edf3get_saltTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3get_contextTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::decrypt: derived key: Ta5d6ff" Tff7b72+ Te6edf3derived_keyTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3Token Td2a8fftokenTb4b4b4(Te6edf3derived_keyTb4b4b4)Tb4b4b4;
T8b949e//ciphertext = ciphertext_token[Identity.KEYSIZE//8//2:]
Te6edf3Bytes Td2a8ffciphertextTb4b4b4(Te6edf3ciphertext_tokenTb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3KEYSIZETff7b72/T79c0ff8Tff7b72/T79c0ff2Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::decrypt: Token decrypting data of length Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3ciphertextTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::decrypt: ciphertext: Ta5d6ff" Tff7b72+ Te6edf3ciphertextTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3plaintext Tff7b72= Te6edf3tokenTb4b4b4.Te6edf3decryptTb4b4b4(Te6edf3ciphertextTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::decrypt: plaintext: Ta5d6ff" Tff7b72+ Te6edf3plaintextTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Identity::decrypt: Token decrypted data of length " + std::to_string(plaintext.size()));
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDecryption by Ta5d6ff" Tff7b72+ Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff failed: Ta5d6ff" Tff7b72+ Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3plaintextTb4b4b4;
Tb4b4b4}
T8b949e/*
Signs information by the identity.
:param message: The message to be signed as *bytes*.
:returns: Signature as *bytes*.
:raises: *KeyError* if the instance does not hold a private key.
*/
Tff7b72const Te6edf3Bytes Te6edf3IdentityTff7b72:Tff7b72:Te6edf3signTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3messageTb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_prvTb4b4b4) Tb4b4b4{
Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3runtime_errorTb4b4b4(Ta5d6ff"Ta5d6ffSigning failed because identity does not hold a private keyTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72try Tb4b4b4{
Tff7b72return Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_prvTff7b72-Tff7b72>Te6edf3signTb4b4b4(Te6edf3messageTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffThe identity Ta5d6ff" Tff7b72+ Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff could not sign the requested message. The contained exception was: Ta5d6ff" Tff7b72+ Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72throw Te6edf3eTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*
Validates the signature of a signed message.
:param signature: The signature to be validated as *bytes*.
:param message: The message to be validated as *bytes*.
:returns: True if the signature is valid, otherwise False.
:raises: *KeyError* if the instance does not hold a public key.
*/
Tffa657bool Te6edf3IdentityTff7b72:Tff7b72:Te6edf3validateTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3signatureTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3messageTb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_objectTff7b72-Tff7b72>Te6edf3_pubTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::validate: Attempting to verify signature: Ta5d6ff" Tff7b72+ Te6edf3signatureTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff and message: Ta5d6ff" Tff7b72+ Te6edf3messageTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_objectTff7b72-Tff7b72>Te6edf3_sig_pubTff7b72-Tff7b72>Te6edf3verifyTb4b4b4(Te6edf3signatureTb4b4b4, Te6edf3messageTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3runtime_errorTb4b4b4(Ta5d6ff"Ta5d6ffSignature validation failed because identity does not hold a public keyTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657void Te6edf3IdentityTff7b72:Tff7b72:Te6edf3proveTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4, Tff7b72const Te6edf3DestinationTff7b72& Te6edf3destination T8b949e/*= {Type::NONE}*/Tb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3assertTb4b4b4(Te6edf3_objectTb4b4b4)Tb4b4b4;
Te6edf3Bytes Td2a8ffsignatureTb4b4b4(Te6edf3signTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3proof_dataTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3should_use_implicit_proofTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3proof_data Tff7b72= Te6edf3signatureTb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::prove: implicit proof data: Ta5d6ff" Tff7b72+ Te6edf3proof_dataTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3proof_data Tff7b72= Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3signatureTb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::prove: explicit proof data: Ta5d6ff" Tff7b72+ Te6edf3proof_dataTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3destinationTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::prove: proving packet with proof destination...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3ProofDestination Te6edf3proof_destination Tff7b72= Te6edf3packetTb4b4b4.Te6edf3generate_proof_destinationTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3Packet Td2a8ffproofTb4b4b4(Te6edf3proof_destinationTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3proof_dataTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PROOFTb4b4b4)Tb4b4b4;
Te6edf3proofTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffIdentity::prove: proving packet with specified destination...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3Packet Td2a8ffproofTb4b4b4(Te6edf3destinationTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3proof_dataTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PROOFTb4b4b4)Tb4b4b4;
Te6edf3proofTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657void Te6edf3IdentityTff7b72:Tff7b72:Te6edf3proveTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tff7b72const Tb4b4b4{
Te6edf3proveTb4b4b4(Te6edf3packetTb4b4b4, Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Served by rngit 1.4.2 - Generated in 0.07s